// 此时要用到ObjectPool，脱离对new/ delete的依赖
#include "ObjectPool.h"
#include "ConcurrentAlloc.h"
#include "mutex"

std::mutex mtx;// 输出锁，保证多线程测试情况下向显示器原子打印输出结果。


void Alloc1()
{
	for (int i = 1; i <= 5; i++)
	{
		void *ptr = ConcurrentAlloc(6);
	}
}

void Alloc2()
{
	for (int i = 1; i < 7; i++)
	{
		void *ptr = ConcurrentAlloc(7);
	}
}

void TLSTest()
{
	std::thread t1(Alloc1);
	t1.join();

	std::thread t2(Alloc2);
	t2.join();

	cout << sizeof(PAGE_ID) << endl;
	cout << sizeof(void*) << endl;	// 跨平台功能验证
}

void TestConcurrentAlloc1()
{
	void* p1 = ConcurrentAlloc(6);
	void* p2 = ConcurrentAlloc(8);
	void* p3 = ConcurrentAlloc(1);
	void* p4 = ConcurrentAlloc(7);
	void* p5 = ConcurrentAlloc(8);

	cout << p1 << endl;
	cout << p2 << endl;
	cout << p3 << endl;
	cout << p4 << endl;
	cout << p5 << endl;
}

void TestConcurrentAlloc2()
{
	for (size_t i = 0; i < 1024; ++i)
	{
		void* p1 = ConcurrentAlloc(6);
		cout << p1 << endl;
	}

	void* p2 = ConcurrentAlloc(8);
	void* p3 = ConcurrentAlloc(1);
	cout << p2 << endl;
	cout << p3 << endl;
}

void MultiThreadAlloc1()
{
	std::vector<void*> v;
	for (size_t i = 0; i < 7; i++)
	{
		void* ptr = ConcurrentAlloc(6);
		v.push_back(ptr);
	}
	for (size_t i = 0; i < 7; i++)
	{
		::mtx.lock();
		cout <<"thread_1:"<< v[i] << endl;
		::mtx.unlock();
		ConcurrentFree(v[i]);
	}
	::mtx.lock();

	cout << "thread_1:" << std::this_thread::get_id() << "exited" << endl;
	::mtx.unlock();

}

void MultiThreadAlloc2()
{
	std::vector<void*> v;
	for (size_t i = 0; i < 7; i++)
	{
		void* ptr = ConcurrentAlloc(6);
		v.push_back(ptr);
	}
	for (size_t i = 0; i < 7; i++)
	{
		mtx.lock();
		cout << "Thread_2:" << v[i] << endl;
		mtx.unlock();
		ConcurrentFree(v[i]);
	}
	mtx.lock();
	cout << "thread_2:" << std::this_thread::get_id() << "exited" << endl;
	mtx.unlock();

}



void TestMultiThread()
{
	// 此测试结果，每个得到的地址理应可能不连续。因为thread按照慢增长策略向central cache索要空间，而且两个线程并行，则每个线程所得几个空间地址不连续属于正常现象
	std::thread t1(MultiThreadAlloc1);
	std::thread t2(MultiThreadAlloc2);
	t1.join();
	t2.join();
}

// 大于256KB和128页的内存
void BigAlloc()
{
	void* p1 = ConcurrentAlloc(257 * 1024);
	ConcurrentFree(p1);

	void* p2 = ConcurrentAlloc(129 * 8 * 1024);
	ConcurrentFree(p2);
}


//int main()
//{
//	//TLSTest();//测试TLS是否能为每个线程分配一个独立变量
//	//TestConcurrentAlloc1();
//	//TestConcurrentAlloc2(); 
//	//TestConcurrentAlloc2(); 
//	//TestMultiThread();
//	//BigAlloc();
//	return 0;
//}

